home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-20 / nrd33.zip / NRDIO.PAS < prev    next >
Pascal/Delphi Source File  |  1991-05-14  |  22KB  |  822 lines

  1. {$I-}
  2. {$V-}
  3.  
  4. unit nrdio;
  5.  
  6. interface
  7.  
  8. const DATELEN     = 6;
  9.       TIMELEN     = 4;
  10.       LONGSTRLEN  = 255;
  11.       MEDSTRLEN   = 80;
  12.       SHORTSTRLEN = 8;
  13.       CALLSIGNLEN = 19;
  14.       LOCATIONLEN = 27;
  15.       COMMENTLEN  = 69;
  16.       MAXREC      = 2500; { maximum records in a log }
  17.       MAXLOGS     = 15;
  18.  
  19.       PATH        = '';
  20.       LOGFILE     = 'LOG';
  21.       RECFILE     = 'REC';
  22.       RECDATAFILE = 'RECDAT';
  23.       LOGLISTFILE = 'LOGLIST.DAT';
  24.  
  25.       FILE_NOT_FOUND = 2;
  26.  
  27. type  longstr       = string[LONGSTRLEN];
  28.       datetype      = string[DATELEN];
  29.       timetype      = string[TIMELEN];
  30.       calltype      = string[CALLSIGNLEN];
  31.       locationtype  = string[LOCATIONLEN];
  32.       commenttype   = string[COMMENTLEN];
  33.  
  34.       modetype      = (RTTY, CW, USB, LSB, AM, FM, FAX, ECSS_USB, ECSS_LSB);
  35.       bandwidthtype = (NARR, INTER, WIDE, AUX);
  36.       agctype       = (OFF, FAST, SLOW);
  37.       attentype     = (NO, YES);
  38.       rectype       = (SHOW, HIDE, DELETED);
  39.  
  40.       logtype = record
  41.                   date:       datetype;
  42.                   begin_time,
  43.                   end_time:   timetype;
  44.                   frequency:  real;
  45.                   callsign:   calltype;
  46.                   location:   locationtype;
  47.                   comment:    commenttype;
  48.                   mode:       modetype;
  49.                   bandwidth:  bandwidthtype;
  50.                   agc:        agctype;
  51.                   attenuator: attentype;
  52.                 end;
  53.  
  54.       recarraytype = packed array[1..MAXREC] of 0..MAXREC;
  55.  
  56.       recdatatype = packed record
  57.                   recptr:   recarraytype;
  58.                   m7000ptr: recarraytype; { not used }
  59.                   recstat:  packed array[1..MAXREC] of rectype;
  60.                 end;
  61.  
  62.       short_str = string[SHORTSTRLEN];
  63.  
  64.       sort_array_type = array[1..MAXREC] of short_str;
  65.  
  66.       journaltype = record
  67.                   logname:  short_str;
  68.                   records,
  69.                   rec:      integer;
  70.                 end;
  71.  
  72.       loglisttype = record
  73.                   logcount,
  74.                   currentlog: byte;
  75.                   log:         array[1..MAXLOGS] of journaltype;
  76.                 end;
  77.  
  78.       configtype = record
  79.                   com_port:byte;
  80.                   receiver_type:word;
  81.                   has_map:boolean;
  82.                   time_offset:byte;
  83.                 end;
  84.  
  85.       receivertype = record
  86.                   channel:    byte;
  87.                   frequency:  real;
  88.                   mode:       modetype;
  89.                   bandwidth:  bandwidthtype;
  90.                   agc:        agctype;
  91.                   attenuator: attentype;
  92.                 end;
  93.  
  94.   var recbuf, recdatabuf, loglistbuf:file;
  95.       recdata:recdatatype;
  96.       records:integer;     { total number of records }
  97.       loglist:loglisttype;
  98.       rec:integer;
  99.       receiverstat:receivertype;
  100.       has_map:boolean;
  101.       com_nrd:byte;
  102.       radio_type:word;
  103.       gmt_offset:byte;
  104.  
  105.   procedure get_records(var records:integer);
  106.   procedure put_records(records:word);
  107.   procedure get_recdata(thelog:byte; var recdata:recdatatype);
  108.   procedure put_recdata(thelog:byte; recdata:recdatatype);
  109.   procedure open_log(var logbuf: file; thelog:byte; var rslt:integer);
  110.   procedure get_log(var logbuf:file; var logdata:logtype; rec:integer);
  111.   procedure put_log(var logbuf:file; logdata:logtype; rec:integer);
  112.   procedure get_loglist(var loglist:loglisttype);
  113.   procedure put_loglist(loglist:loglisttype);
  114.   procedure init_com; { open com and set up for session }
  115.   procedure write_com(port:byte; s:string);
  116.   procedure comreadln(port:byte; var s:string);
  117.   procedure remote_on;{ enable remote control of radio, get receiver status }
  118.   procedure remote_off(dly:word);
  119.   procedure toggle_remote;
  120.   procedure check_status(var s:string);
  121.   procedure set_freq(frequency:real);
  122.   procedure set_mode(mode:modetype);
  123.   procedure set_bandwidth(bandwidth:bandwidthtype);
  124.   procedure set_agc(agc:agctype);
  125.   procedure set_attenuator(attenuator:attentype);
  126.   procedure set_all(channel:byte; attenuator:attentype;
  127.                      bandwidth:bandwidthtype; mode:modetype; frequency:real;
  128.                      agc:agctype);
  129.  
  130.   implementation
  131.  
  132.   uses async, crt, dos, screen;
  133.  
  134.   procedure open_records(var rslt:integer);
  135.   var ch:char;
  136.   begin
  137.     assign(recbuf,PATH+RECFILE+'.DAT');
  138.     repeat
  139.       reset(recbuf,sizeof(records));
  140.       rslt:=ioresult;
  141.       if rslt = FILE_NOT_FOUND then
  142.         begin
  143.           rewrite(recbuf,sizeof(records));
  144.           records:=0;
  145.           blockwrite(recbuf,records,1);
  146.           close(recbuf);
  147.           reset(recbuf,sizeof(records));
  148.           rslt:=ioresult;
  149.         end;
  150.       hndlerr(FALSE,ch,rslt);
  151.     until (rslt = 0) or (ch = KEYINFO.ESCKEY);
  152.   end;
  153.  
  154.   procedure get_records;
  155.   var ch:char;
  156.       rslt:integer;
  157.   begin
  158.     open_records(rslt);
  159.     if rslt = 0 then
  160.       begin
  161.         blockread(recbuf,records,1);
  162.         rslt:=ioresult;
  163.         hndlerr(FALSE,ch,rslt);
  164.       end;
  165.     close(recbuf);
  166.   end;
  167.  
  168.   procedure put_records;
  169.   var ch:char;
  170.       rslt:integer;
  171.   begin
  172.     open_records(rslt);
  173.     if rslt = 0 then
  174.       begin
  175.         blockwrite(recbuf,records,1);
  176.         rslt:=ioresult;
  177.         hndlerr(FALSE,ch,rslt);
  178.       end;
  179.     close(recbuf);
  180.   end;
  181.  
  182.   procedure open_recdata(thelog:byte; var rslt:integer);
  183.   var ch:char;
  184.       s:string;
  185.       i:integer;
  186.   begin
  187.     str(thelog,s);
  188.     if length(s) = 1 then s:='0' + s;
  189.     assign(recdatabuf,PATH+RECDATAFILE + s + '.DAT');
  190.     repeat
  191.       reset(recdatabuf,sizeof(recdata));
  192.       rslt:=ioresult;
  193.       if rslt = FILE_NOT_FOUND then
  194.         begin
  195.           for i:=1 to MAXREC do with recdata do
  196.             begin
  197.               if i <= records then
  198.                 begin
  199.                    recptr[i]:= i;
  200.                    recstat[i]:= SHOW
  201.                 end
  202.               else
  203.                 begin
  204.                   recptr[i]:=0;
  205.                   recstat[i]:=DELETED;
  206.                 end;
  207.               m7000ptr[i]:=0;
  208.             end;
  209.           rewrite(recdatabuf,sizeof(recdata));
  210.           blockwrite(recdatabuf,recdata,1);
  211.           close(recdatabuf);
  212.           reset(recdatabuf,sizeof(recdata));
  213.           rslt:=ioresult;
  214.         end;
  215.       hndlerr(FALSE,ch,rslt);
  216.     until (rslt = 0) or (ch = KEYINFO.ESCKEY);
  217.   end;
  218.  
  219.   procedure get_recdata;
  220.  
  221.   var ch:char;
  222.       rslt:integer;
  223.   begin
  224.     open_recdata(thelog,rslt);
  225.     if rslt = 0 then
  226.       begin
  227.         blockread(recdatabuf,recdata,1);
  228.         rslt:=ioresult;
  229.         hndlerr(FALSE,ch,rslt);
  230.       end;
  231.     close(recdatabuf);
  232.   end;
  233.  
  234.   procedure put_recdata;
  235.  
  236.   var ch:char;
  237.       rslt:integer;
  238.   begin
  239.     open_recdata(thelog,rslt);
  240.     if rslt = 0 then
  241.       begin
  242.         blockwrite(recdatabuf,recdata,1);
  243.         rslt:=ioresult;
  244.         hndlerr(FALSE,ch,rslt);
  245.       end;
  246.     close(recdatabuf);
  247.   end;
  248.  
  249.   procedure open_log;
  250.  
  251.   var ch:char;
  252.       s:string;
  253.   begin
  254.     str(thelog,s);
  255.     if length(s) = 1 then s:='0'+s;
  256.     assign(logbuf,PATH+LOGFILE+s+'.DAT');
  257.     reset(logbuf,sizeof(logtype));
  258.     repeat
  259.       rslt:=IORESULT;
  260.       if rslt = FILE_NOT_FOUND then
  261.         begin
  262.           rewrite(logbuf,sizeof(logtype));
  263.           rslt:=ioresult;
  264.         end;
  265.       hndlerr(FALSE,ch,rslt);
  266.     until (rslt = 0) or (ch = KEYINFO.ESCKEY);
  267.   end;
  268.  
  269.   procedure get_log;
  270.  
  271.   var rslt:integer;
  272.       ch:char;
  273.   begin
  274.     seek(logbuf,rec - 1);
  275.     blockread(logbuf,logdata,1);
  276.     rslt:=ioresult;
  277.     if rslt > 0 then
  278.       begin
  279.         hndlerr(TRUE,ch,rslt);
  280.       end;
  281.   end;
  282.  
  283.   procedure put_log;
  284.  
  285.   var ch:char;
  286.       rslt:integer;
  287.  
  288.   begin
  289.     seek(logbuf,rec - 1);
  290.     blockwrite(logbuf,logdata,1);
  291.     rslt:=ioresult;
  292.     if rslt > 0 then
  293.       begin
  294.         hndlerr(TRUE,ch,rslt);
  295.       end;
  296.   end;
  297.  
  298.  
  299.  
  300.   procedure open_loglist(var rslt:integer);
  301.   var ch:char;
  302.   begin
  303.     assign(loglistbuf,PATH+LOGLISTFILE);
  304.     repeat
  305.       reset(loglistbuf,sizeof(loglisttype));
  306.       rslt:=ioresult;
  307.       if rslt = FILE_NOT_FOUND then
  308.         begin
  309.           rewrite(loglistbuf,sizeof(loglisttype));
  310.           loglist.logcount:=0;
  311.           blockwrite(loglistbuf,loglist,1);
  312.           close(loglistbuf);
  313.           reset(loglistbuf,sizeof(loglisttype));
  314.           rslt:=ioresult;
  315.         end;
  316.       hndlerr(FALSE,ch,rslt);
  317.     until (rslt = 0) or (ch = KEYINFO.ESCKEY);
  318.   end;
  319.  
  320.   procedure get_loglist;
  321.  
  322.   var ch:char;
  323.       rslt:integer;
  324.   begin
  325.     open_loglist(rslt);
  326.     if rslt = 0 then
  327.       begin
  328.         blockread(loglistbuf,loglist,1);
  329.         if loglist.logcount = 0 then
  330.           begin
  331.             records:=0;
  332.             rec:=1;
  333.           end
  334.         else
  335.           begin
  336.             records:=loglist.log[loglist.currentlog].records;
  337.             rec:=    loglist.log[loglist.currentlog].rec;
  338.           end;
  339.         rslt:=ioresult;
  340.         hndlerr(FALSE,ch,rslt);
  341.       end;
  342.     close(loglistbuf);
  343.   end;
  344.  
  345.   procedure put_loglist;
  346.  
  347.   var ch:char;
  348.       rslt:integer;
  349.   begin
  350.     open_loglist(rslt);
  351.     if rslt = 0 then
  352.       begin
  353.         blockwrite(loglistbuf,loglist,1);
  354.         rslt:=ioresult;
  355.         hndlerr(FALSE,ch,rslt);
  356.       end;
  357.     close(loglistbuf);
  358.   end;
  359.  
  360.   procedure init_com; { open com and set up for session }
  361.   var baud:integer;
  362.   begin
  363.     if radio_type = 525 then baud:=1200 else
  364.     if radio_type = 535 then baud:=4800;
  365.     async_init;
  366.     if COM_NRD = 0 then exit;
  367.     if not async_open(COM_NRD,baud,'N',8,1) then
  368.       begin
  369.         writeln('Com port failure');
  370.         halt;
  371.       end;
  372.   end;
  373.  
  374.   procedure write_com;
  375.   begin
  376.     if COM_NRD = 0 then exit;
  377.     if radio_type = 535 then s:=s + chr(13);
  378.     async_send_string(s);
  379.   end;
  380.  
  381.   procedure comreadln;
  382.   var ch:char;
  383.       gotchar, done:boolean;
  384.       error_count:integer;
  385.   begin
  386.     s:='';
  387.     if COM_NRD = 0 then
  388.       begin
  389.         s:='000000';
  390.         exit;
  391.       end;
  392.     done:=FALSE;
  393.     error_count:=0;
  394.     while not done do
  395.       begin
  396.         gotchar:=async_buffer_check(ch);
  397.         if  not gotchar then
  398.           begin
  399.             delay(20);
  400.             inc(error_count);
  401.           end
  402.         else error_count:=0;
  403.         if error_count > 40 then exit;
  404.         done:=ch = #013;
  405.         if not done and gotchar then s:=s + ch;
  406.       end;
  407.   end;
  408.  
  409.   procedure check_status; { used to read status of nrd 535 }
  410.   var ch:char;
  411.       s1:string;
  412.       dummy:integer;
  413.   begin
  414.     comreadln(COM_NRD,s);
  415.     s:='I'+s;
  416.     with receiverstat do
  417.       begin
  418.         { get attenuator status }
  419.         ch:=s[2];
  420.         case ch of
  421.           '0': attenuator:=NO;
  422.           '1': attenuator:=YES;
  423.           else attenuator:=YES; { error condition }
  424.         end;
  425.  
  426.         { get bandwidth }
  427.         ch:=s[3];
  428.         case ch of
  429.           '0': bandwidth:=WIDE;
  430.           '1': bandwidth:=INTER;
  431.           '2': bandwidth:=NARR;
  432.           '3': bandwidth:=AUX;
  433.           else bandwidth:=AUX; { error condition }
  434.         end;
  435.  
  436.         { get receiver mode }
  437.         ch:=s[4];
  438.         case ch of
  439.           '0': mode:=RTTY;
  440.           '1': mode:=CW;
  441.           '2': mode:=USB;
  442.           '3': mode:=LSB;
  443.           '4': mode:=AM;
  444.           '5': mode:=FM;
  445.           '6': mode:=FAX;
  446.           '7': mode:=ECSS_USB;
  447.           '8': mode:=ECSS_LSB;
  448.           else mode:=FM; { error condition }
  449.         end;
  450.  
  451.         { get frequency }
  452.         s1:=copy(s,5,8);
  453.         val(s1,frequency,dummy);
  454.         frequency:=frequency / 1000.0;
  455.  
  456.         { get agc setting }
  457.         ch:=s[13];
  458.         case ch of
  459.           '0': agc:=SLOW;
  460.           '1': agc:=FAST;
  461.           '2': agc:=OFF;
  462.           else agc:=OFF; { error condition }
  463.         end;
  464.       end;
  465.   end;
  466.  
  467.   procedure remote_on;
  468.   { enable remote control of radio, get receiver status }
  469.   const ECHO   = FALSE;
  470.         STRLEN = 40;
  471.   var s,s1:string;
  472.       dummy:integer;
  473.       ch:char;
  474.  
  475.     procedure initiate_remote; { send remote on string }
  476.     begin
  477.       write_com(COM_NRD,'H1');      { enable receiver remote mode }
  478.     end;
  479.  
  480.     procedure check_serial_port(var s1:string);
  481.  
  482.     { This is a bizarre procedure to minimize program hanging in the event
  483.       that the radio is left off or the serial port is selected to another
  484.       device.  It uses an algorithm that assumes that no response to the
  485.       remote command is an indication of error as is receiving a response
  486.       back that does not begin in "C".  The latter can happen if the serial
  487.       port is attached to a modem for example...}
  488.  
  489.       procedure check_response(ch:char; var s1:string);
  490.       var ch1:char;
  491.       begin
  492.         if ch = 'C' then { all is (assumed) ok }
  493.           begin
  494.             s1:=' '; s1[1]:=ch;
  495.           end
  496.         else
  497.           begin
  498.             writeln(output,
  499.   'Improper response from radio --- check connections and re-run program');
  500.             writeln(output,'Hit any key to continue');
  501.             repeat until keypressed;
  502.             ch1:=readkey;
  503.             halt;
  504.           end;
  505.       end;
  506.  
  507.     var ch, ch1:char;
  508.     begin
  509.       if com_nrd = 0 then { abort check }
  510.         begin
  511.           s1:='';
  512.           exit;
  513.         end;
  514.       if not async_buffer_check(ch) then { something is wrong }
  515.         begin
  516.           delay(250); { just in case }
  517.           if not async_buffer_check(ch) then { hung for sure }
  518.             begin
  519.               writeln(output,
  520.               'No response from receiver.  Correct and hit any key');
  521.               repeat until keypressed;
  522.               ch1:=readkey;
  523.               s1:='';
  524.               initiate_remote;
  525.             end
  526.           else check_response(ch,s1);
  527.         end
  528.       else check_response(ch,s1);
  529.     end;
  530.  
  531.   begin
  532.     if com_nrd > 0 then while async_buffer_check(ch) do;
  533.             { nrd sometimes leaves stuff behind }
  534.     initiate_remote;
  535.     if radio_type = 535 then exit
  536.     else
  537.       begin
  538.         check_serial_port(s1); { will return 1st char in s1 }
  539.         with receiverstat do
  540.           begin
  541.             { get channel }
  542.             comreadln(COM_NRD,s);
  543.             s:=s1 + s;
  544.             delete(s,1,1); { remove "C" }
  545.             val(s,channel,dummy);
  546.  
  547.             { get receiver mode }
  548.             comreadln(COM_NRD,s);
  549.             ch:=s[2];
  550.             case ch of
  551.               '0': mode:=RTTY;
  552.               '1': mode:=CW;
  553.               '2': mode:=USB;
  554.               '3': mode:=LSB;
  555.               '4': mode:=AM;
  556.               '5': mode:=FM;
  557.               '6': mode:=FAX;
  558.               else mode:=FM; { error condition }
  559.             end;
  560.  
  561.             { get agc setting }
  562.             comreadln(COM_NRD,s);
  563.             ch:=s[2];
  564.             case ch of
  565.               '0': agc:=SLOW;
  566.               '1': agc:=FAST;
  567.               '2': agc:=OFF;
  568.               else agc:=OFF; { error condition }
  569.             end;
  570.  
  571.             { get attenuator status }
  572.             comreadln(COM_NRD,s);
  573.             ch:=s[2];
  574.             case ch of
  575.               '0': attenuator:=NO;
  576.               '1': attenuator:=YES;
  577.               else attenuator:=YES; { error condition }
  578.             end;
  579.  
  580.             { get bandwidth }
  581.             comreadln(COM_NRD,s);
  582.             ch:=s[2];
  583.             case ch of
  584.               '0': bandwidth:=WIDE;
  585.               '1': bandwidth:=INTER;
  586.               '2': bandwidth:=NARR;
  587.               '3': bandwidth:=AUX;
  588.               else bandwidth:=AUX; { error condition }
  589.             end;
  590.  
  591.             { get frequency }
  592.             comreadln(COM_NRD,s);
  593.             delete(s,1,1); { get rid of "F" }
  594.             val(s,frequency,dummy);
  595.             frequency:=frequency / 100.0;
  596.           end;
  597.       end;
  598.   end;
  599.  
  600.   procedure remote_off;
  601.   begin
  602.     if radio_type = 535 then exit;
  603.     write_com(COM_NRD,'H0'); { disable receiver remote mode }
  604.     delay(dly);
  605.   end;
  606.  
  607.   procedure toggle_remote; { unlock radio }
  608.   var ch:char;
  609.       s:string;
  610.   begin
  611.     write_com(COM_NRD,'I0');
  612.     write_com(COM_NRD,'I1');
  613.     delay(200);
  614.     if async_buffer_check(ch) then check_status(s);
  615.   end;
  616.  
  617.   procedure set_freq;
  618.   var s:string;
  619.   begin
  620.     str(frequency:8:2,s);
  621.     while s[1] = ' ' do delete(s,1,1);
  622.     while length(s) < 9 do s:=concat('0',s);
  623.     s:=concat('F',s);
  624.     delete(s,8,1); { remove "." }
  625.     if radio_type = 535 then
  626.       begin
  627.         delete(s,2,1);
  628.         s:=s + '0';
  629.       end;
  630.     write_com(COM_NRD,s);
  631.     if radio_type = 525 then comreadln(COM_NRD,s);
  632.   end;
  633.  
  634.   procedure set_mode;
  635.   var ch:char;
  636.       s:string;
  637.   begin
  638.     case mode of
  639.       RTTY:     s:='0';
  640.       CW:       s:='1';
  641.       USB:      s:='2';
  642.       LSB:      s:='3';
  643.       AM:       s:='4';
  644.       FM:       s:='5';
  645.       FAX:      s:='6';
  646.       ECSS_USB: s:='7';
  647.       ECSS_LSB: s:='8';
  648.     end;
  649.     s:=concat('D',s);
  650.     write_com(COM_NRD,s);
  651.     if radio_type = 525 then comreadln(COM_NRD,s);
  652.   end;
  653.  
  654.   procedure set_bandwidth;
  655.   var ch:char;
  656.       s:string;
  657.   begin
  658.     case bandwidth of
  659.       WIDE:  s:='0';
  660.       INTER: s:='1';
  661.       NARR:  s:='2';
  662.       AUX:   s:='3';
  663.     end;
  664.     s:=concat('B',s);
  665.     write_com(COM_NRD,s);
  666.     if radio_type = 525 then comreadln(COM_NRD,s);
  667.   end;
  668.  
  669.   procedure set_agc;
  670.   var ch:char;
  671.       s:string;
  672.   begin
  673.     case agc of
  674.       SLOW:  s:='0';
  675.       FAST:  s:='1';
  676.       OFF:   s:='2';
  677.     end;
  678.     s:=concat('G',s);
  679.     write_com(COM_NRD,s);
  680.     comreadln(COM_NRD,s);
  681.   end;
  682.  
  683.   procedure set_attenuator;
  684.   var ch:char;
  685.       s:string;
  686.   begin
  687.     case attenuator of
  688.       NO:  s:='0';
  689.       YES: s:='1';
  690.     end;
  691.     s:=concat('A',s);
  692.     write_com(COM_NRD,s);
  693.     comreadln(COM_NRD,s);
  694.   end;
  695.  
  696.   procedure set_all; { used to set all parameters for an NRD535 }
  697.   var s,s1:string;
  698.   begin
  699.     s:='S';
  700.     str(channel,s1);
  701.     while length(s1) < 3 do s1:='0' + s1;
  702.     s:=s + s1;
  703.     case attenuator of
  704.       NO: s:=s + '0';
  705.       YES:s:=s + '1';
  706.     end;
  707.     case bandwidth of
  708.       WIDE:  s:=s + '0';
  709.       INTER: s:=s + '1';
  710.       NARR:  s:=s + '2';
  711.       AUX:   s:=s + '3';
  712.     end;
  713.     case mode of
  714.       RTTY:     s:=s + '0';
  715.       CW:       s:=s + '1';
  716.       USB:      s:=s + '2';
  717.       LSB:      s:=s + '3';
  718.       AM:       s:=s + '4';
  719.       FM:       s:=s + '5';
  720.       FAX:      s:=s + '6';
  721.       ECSS_USB: s:=s + '7';
  722.       ECSS_LSB: s:=s + '8';
  723.     end;
  724.     str(frequency:8:2,s1);
  725.     while s1[1] = ' ' do delete(s1,1,1);
  726.     while length(s1) < 8 do s1:=concat('0',s1);
  727.     delete(s1,6,1); { remove "." }
  728.     s:=s + s1 + '00';
  729.     write_com(COM_NRD,s);
  730.   end;
  731.  
  732.   procedure init; { initialize port address, file path and existence of MAP }
  733.   const CONFIG_PATH = 'CONFIG.DAT';
  734.   var buf:file;
  735.       configdat:configtype;
  736.       num:integer;
  737.  
  738.     procedure open_config(var rslt:integer);
  739.     var ch:char;
  740.         ok,dummy:boolean;
  741.         hour,minute,sec,sec100:word;
  742.         s:string;
  743.     begin
  744.       assign(buf,CONFIG_PATH);
  745.       repeat
  746.         reset(buf,sizeof(configdat));
  747.         rslt:=ioresult;
  748.         if rslt = FILE_NOT_FOUND then
  749.           begin
  750.             repeat
  751.               home;
  752.               writea(LIGHTGREEN, FOREGROUND);
  753.               writeln(output,
  754.   'System could not find Config.dat file.  Please answer these questions');
  755.               writeln(output,
  756.   'about your system and Config.dat will be created for you...');
  757.               entnum(0,10,num,ok,dummy,
  758.                    'your com port (eg 1 for COM1:, 0 for demo):');
  759.               if num in [0..4] then configdat.com_port:=num;
  760.               if not ok then halt;
  761.             until num in [0..4];
  762.             writeln(output);
  763.             writea(LIGHTGREEN, FOREGROUND);
  764.             repeat
  765.               write(output,'Enter receiver type (525 or 535):');
  766.               readln(input,s);
  767.             until (s = '525') or (s = '535');
  768.             if s = '525' then configdat.receiver_type:=525
  769.                          else configdat.receiver_type:=535;
  770.             if configdat.receiver_type = 525 then
  771.               begin
  772.                 write(output,'Do you have a KIWA MAP unit? (y=yes):');
  773.                 read(input,ch);
  774.                 configdat.has_map:=ch in ['y','Y'];
  775.                 writeln(output);
  776.               end
  777.             else configdat.has_map:=FALSE;
  778.             writeln(output,
  779. 'Now we will adjust the time offset so time is referenced to GMT.');
  780.             writeln(output,
  781. 'Enter the hour only (not minutes) in GMT (eg if GMT = 16:47, enter 16.');
  782.             entnum(0,17,num,ok,dummy,'the');
  783.             if not ok then halt;
  784.             gettime(hour,minute,sec,sec100);
  785.             configdat.time_offset:=num - hour;
  786.             rewrite(buf,sizeof(configdat));
  787.             blockwrite(buf,configdat,1);
  788.             close(buf);
  789.             reset(buf,sizeof(configdat));
  790.             rslt:=ioresult;
  791.           end;
  792.         hndlerr(FALSE,ch,rslt);
  793.       until (rslt = 0) or (ch = KEYINFO.ESCKEY);
  794.     end;
  795.  
  796.     procedure get_config;
  797.     var ch:char;
  798.         rslt:integer;
  799.     begin
  800.       open_config(rslt);
  801.       if rslt = 0 then
  802.         begin
  803.           blockread(buf,configdat,1);
  804.           rslt:=ioresult;
  805.           hndlerr(FALSE,ch,rslt);
  806.         end;
  807.       com_nrd:=configdat.com_port;
  808.       has_map:=configdat.has_map;
  809.       radio_type:=configdat.receiver_type;
  810.       gmt_offset:=configdat.time_offset;
  811.       close(buf);
  812.     end;
  813.  
  814.   begin
  815.     get_config;
  816.   end;
  817.  
  818. begin
  819.   init
  820. end.
  821.  
  822.